<template>
    <ClientOnly>
        <popup
            :show="visible"
            width="800px"
            title="关键词推荐"
            :footer-border="true"
            confirmButtonText="确定描述词"
            cancelButtonText="替换描述词"
            @confirm="handlePromptAdd"
            @cancel="handleAlternatePrompt"
        >
            <template #trigger>
                <slot name="trigger"></slot>
            </template>

            <div class="flex">
                <template v-if="categoryLists.length > 0">
                    <el-scrollbar class="w-[110px] bg-page" height="500px">
                        <div class="left-menus">
                            <div
                                v-for="(item, index) in categoryLists"
                                :key="index"
                                class="menu-item"
                                :class="{ active: index === categoryIndex }"
                                @click="changeCategory(index)"
                            >
                                {{ item.name }}
                            </div>
                        </div>
                    </el-scrollbar>
                    <div class="p-4 flex-1">
                        <template v-if="promptLists.length > 0">
                            <div
                                v-for="(item, index) in (promptLists as DrawsPromptLexiconResponse[])"
                                :key="index"
                                class="keyword-item"
                                :class="{'active': promptActive.includes(item.prompt_en)}"
                                @click="handleChoicePrompt(item.prompt_en)"
                            >
                                {{ item?.prompt_en }}｜{{ item.prompt }}
                            </div>
                        </template>
                        <template v-else>
                            <div class="flex items-center justify-center w-full">
                                <el-result title="提示" sub-title="暂无数据">>
                                    <template #icon>
                                        <el-image class="w-[200px] h-[200px]" :src="PromptEmpty" />
                                    </template>
                                </el-result>
                            </div>
                        </template>
                    </div>
                </template>

                <template v-else>
                    <div class="flex items-center justify-center w-full h-[500px]">
                        <el-result title="提示" sub-title="暂无相关关键词">>
                            <template #icon>
                                <el-image class="w-[200px] h-[200px]" :src="PromptEmpty" />
                            </template>
                        </el-result>
                    </div>
                </template>
            </div>
        </popup>
    </ClientOnly>
</template>

<script lang="ts" setup>
import drawsPromptApi from '~/api/apply/draws/prompt'
import PromptEmpty from '~/assets/image/draw/empty.png'

const emits = defineEmits<{
    (event: 'update:modelValue', value: string): void
}>()

const props = defineProps({
    // 关键词值
    modelValue: {
        type: String,
        default: ''
    },
    // 绘画引擎
    engine: {
        type: String,
        default: ''
    }
})

// 显示弹窗
const visible = ref(false)

// 分类数据
const categoryIndex = ref<number>(0)
const categoryLists = ref<DrawsPromptCategoryResponse[]>([])

// 提示词数据
const promptActive = ref<string[]>([])
const promptLists = ref<DrawsPromptLexiconResponse[]>([])

/**
 * 选择关键词
 */
const handleChoicePrompt = (text: string) => {
    const index = promptActive.value.findIndex((item: string) => item === text)
    if (index >= 0) {
        promptActive.value.splice(index, 1)
        return
    }
    promptActive.value.push(text)
}

/**
 * 加入关键词
 */
const handlePromptAdd = () => {
    if (props.modelValue.trim() === '') {
        const prompt = promptActive.value.length ? promptActive.value.join(',') : ''
        emits('update:modelValue', prompt)
    } else {
        const prompt = promptActive.value.length ? promptActive.value.join(',') : ''
        const keyword = `${props.modelValue} ${prompt ? `,${prompt}` : ''}`
        emits('update:modelValue', keyword)
    }
    visible.value = false
    promptActive.value = []
}

/**
 * 替换关键词
 */
const handleAlternatePrompt = () => {
    const prompt = promptActive.value.length ? promptActive.value.join(',') : ''
    emits('update:modelValue', prompt)
    promptActive.value = []
}

/**
 * 获取关键词分类
 */
const queryKeywordCategory = async () => {
    categoryLists.value = await drawsPromptApi.category(props.engine)
    await queryKeywordPrompt()
}

/**
 * 获取词汇列表
 */
const queryKeywordPrompt = async () => {
    const id = categoryLists.value[categoryIndex.value]?.id
    if (id) {
        promptLists.value = await drawsPromptApi.lexicon(props.engine, id)
    }
}

/**
 * 切换分类
 */
const changeCategory = async (index: number) => {
    categoryIndex.value = index
    await queryKeywordCategory()
}

/**
 * 监听提示词变化
 */
watchEffect(() => {
    const prompt = props.modelValue
    if (prompt === '') {
        promptActive.value = []
    }
})

/**
 * 组件挂载完成后被调用
 */
onMounted(async () => {
    await nextTick()
    await queryKeywordCategory()
})
</script>

<style lang="scss" scoped>
.left-menus {
    .menu-item {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 48px;
        font-size: 13px;
        color: var(--el-text-color-secondary);
        cursor: pointer;
        &.active {
            color: var(--el-color-primary);
            background-color: var(--el-bg-color);
        }
    }
}

.keyword-item {
    display: inline-block;
    padding: 6px 10px;
    margin-right: 10px;
    margin-bottom: 10px;
    color: var(--el-text-color-regular);
    cursor: pointer;
    background-color: var(--el-bg-color-page);
    border-radius: 4px;
    &.active {
        color: var(--el-color-primary);
        background-color: var(--el-color-primary-light-9);
    }
}
</style>
